package com.java.socket.tcp.multiclient.threadpool.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池方式处理多客户端Socket服务端
 *
 * @author xzmeasy
 * @version 1.0
 * @since 星期一 十二月,2018
 */
@SuppressWarnings("Duplicates")
public class ServerSocketExample {

    public static void main(String[] args) {
        try {
            final ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("Socket服务端已经启动...");
            // 创建一个线程池
            final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 20000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
//            System.out.println("活动的线程数量: " + executor.getActiveCount());
//            System.out.println("已经完成的任务数量: " + executor.getCompletedTaskCount());
//            System.out.println("核心线程池大小: " + executor.getCorePoolSize());
//            System.out.println("存活时间大小: " + executor.getKeepAliveTime(TimeUnit.MILLISECONDS));
//            System.out.println("最大线程池大小: " + executor.getLargestPoolSize());
//            System.out.println("线程池最大线程数量: " + executor.getMaximumPoolSize());
//            System.out.println("当前线程池大小: " + executor.getPoolSize());
//            System.out.println("任务数量: " + executor.getTaskCount());
            while (true) {
                final Socket socket = serverSocket.accept();

                // 提交任务到线程池，也可以使用execute()方法，execute()方法没有返回值，而submit()方法有返回值
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            // 从Socket获取输入流，用于获取客户端发送的消息
                            InputStream inputStream = socket.getInputStream();
                            byte[] bytes = new byte[1024];
                            int len = 0;
                            StringBuilder info = new StringBuilder();
                            while ((len = inputStream.read(bytes)) != -1) {
                                info.append(new String(bytes, Charset.forName("utf-8")));
                            }
                            System.out.println("客户端发送的消息: " + info.toString());


                            // 从Socket获取输出流，用于向客户端发送反馈信息
                            OutputStream outputStream = socket.getOutputStream();
                            PrintWriter writer = new PrintWriter(outputStream);
                            String message = "服务段的反馈信息";
                            writer.write(message);
                            writer.flush();


                            // 关闭资源
                            writer.close();
                            outputStream.close();
                            inputStream.close();
                            socket.close();


//                            System.out.println("活动的线程数量: " + executor.getActiveCount());
//                            System.out.println("已经完成的任务数量: " + executor.getCompletedTaskCount());
//                            System.out.println("核心线程池大小: " + executor.getCorePoolSize());
//                            System.out.println("存活时间大小: " + executor.getKeepAliveTime(TimeUnit.MILLISECONDS));
//                            System.out.println("最大线程池大小: " + executor.getLargestPoolSize());
//                            System.out.println("线程池最大线程数量: " + executor.getMaximumPoolSize());
//                            System.out.println("当前线程池大小: " + executor.getPoolSize());
//                            System.out.println("任务数量: " + executor.getTaskCount());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                };
                executor.execute(runnable);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
